<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>垃圾回收机制</title>
  </head>
  <body>
    <script>
      /*
      在 JS 中对象的释放（回收）是靠浏览器中的垃圾回收器来回收处理的
        1. 垃圾回收器
          ● 浏览器中有个专门的线程， 它每隔很短的时间就会运行一次
          ● 主要工作：判断一个对象是否是垃圾对象，如果是，清除其内存数据，并标记内存是空闲状态
        2. 垃圾回收策略
          机制 1：引用计数法 
            这其实是早先的一种垃圾回收算法，它把 对象是否不再需要 简化定义为 对象有没有其他对象引用到它，
            如果没有引用指向该对象（零引用），对象将被垃圾回收机制回收，目前很少使用这种算法了
            它的策略是跟踪记录每个变量值被使用的次数
              如果对象被引用一次，引用次数+1，如果变量的值被其他的值覆盖了，则引用次数-1
              当这个值的引用次数变为 0 的时候，说明没有变量在使用，这个值没法被访问了，回收空间。

          机制 2：标记清除法 
            目前大多数浏览器的实现方案，分为 标记 和 清除 两个阶段，
            标记阶段即为所有活动对象做上标记，清除阶段则把没有标记（也就是非活动对象）销毁
            过程如下：
              垃圾回收器在运行时会给内存中的所有变量都加上一个标记，假设内存中所有对象都是垃圾，全标记为0
              然后从各个根对象开始遍历，把不是垃圾的节点改成1
              清理所有标记为0的垃圾，销毁并回收它们所占用的内存空间
              最后，把所有内存中对象标记修改为0，等待下一轮垃圾回收
            缺点：内存碎片化，内存分配速度慢
            优化：标记整理算法
              标记结束后，标记整理算法会将活着的对象（即不需要清理的对象）向内存的一端移动，最后清理掉边界的内存
            V8引擎还继续优化：分代式垃圾回收
              V8 中将堆内存分为新生代和老生代两区域，采用不同的垃圾回收器也就是不同的策略管理垃圾回收
              新生代的对象为存活时间较短的和体积较小对象通常只支持 1～8M 的容量，
              而老生代的对象为存活时间较长或体积较大对象，简单来说就是经历过新生代垃圾回收后还存活下来的对象（存活时间长）

              新生代区域垃圾回收：
                将内存一分为2（等分），一块称为使用区，一块称为空闲区，一开始对象都在使用区存放着
                开始垃圾回收，将使用区活动对象（有被引用对象）复制到空闲区
                全部执行完，将使用区清空，将空闲区变成使用区，使用区变成空闲区，等待下次垃圾回收

                当满足两个条件其中之一时，对象会从新生代区晋升到老生代区
                1. 经历过新生代垃圾回收后还存活下来的对象
                2. 容量超过使用区25%

              老生代区域垃圾回收：标记整理清除算法

              https://juejin.cn/post/6981588276356317214#heading-9
      */
    </script>
  </body>
</html>
